package com.snail.workflow.controller;

import com.snail.common.core.domain.R;
import com.snail.common.core.web.page.PageResult;
import com.snail.common.log.annotation.Log;
import com.snail.common.log.enums.BusinessType;
import com.snail.common.log.enums.OperatorType;
import com.snail.workflow.api.domain.dto.FlowDefinitionDto;
import com.snail.workflow.api.domain.dto.FlowProcDefDto;
import com.snail.workflow.api.query.FlowProcDefQuery;
import com.snail.workflow.service.IFlowDefinitionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

/**
 * @Description: 流程定义
 * @Author: Snail
 * @CreateDate: 2022/7/26 21:00
 * @Version: V1.0
 */
@Api(tags = "流程定义功能")
@RestController
@RequestMapping("/definition")
public class FlowDefinitionController {

    @Autowired
    private IFlowDefinitionService flowDefinitionService;

    @Log(title = "查询流程定义列表", businessType = BusinessType.OTHER, operatorType = OperatorType.OTHER)
    @ApiOperation(value = "查询流程定义列表")
    @GetMapping("/list")
    public R<PageResult<FlowProcDefDto>> listFlowProcDef(FlowProcDefQuery flowProcDefQuery) {
        return R.ok(flowDefinitionService.listFlowProcDef(flowProcDefQuery));
    }

    @Log(title = "部署流程(xml)", businessType = BusinessType.OTHER, operatorType = OperatorType.OTHER)
    @ApiOperation(value = "部署流程(xml)")
    @PostMapping("/deployXml")
    public R<String> importXml(@RequestBody FlowDefinitionDto flowDefinitionDto) {
        String deployId = "0";
        try {
            String xml = URLDecoder.decode(flowDefinitionDto.getXml(), "UTF-8");
            InputStream in = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
            deployId = flowDefinitionService.deploy(flowDefinitionDto.getWfName(), flowDefinitionDto.getWfCategory(), in);
        } catch (IOException e) {
            R.fail("流程部署失败：" + e.getMessage());
        }
        return R.ok(deployId);
    }

    @Log(title = "部署流程(file)", businessType = BusinessType.OTHER, operatorType = OperatorType.OTHER)
    @ApiOperation(value = "部署流程(file)", notes = "上传bpmn20的xml文件")
    @PostMapping("/importFile")
    public R<Boolean> importFile(String wfName, String wfCategory,
                                 @RequestPart("file") MultipartFile file) {
        return R.ok(flowDefinitionService.importFile(wfName, wfCategory, file));
    }

    @Log(title = "读取流程xml文件", businessType = BusinessType.OTHER, operatorType = OperatorType.OTHER)
    @ApiOperation(value = "读取xml文件")
    @GetMapping("/readXml/{deployId}")
    public R<FlowDefinitionDto> readXml(@PathVariable("deployId") String deployId) {
        return R.ok(flowDefinitionService.readXml(deployId));
    }

    @Log(title = "读取流程图片）", businessType = BusinessType.OTHER, operatorType = OperatorType.OTHER)
    @ApiOperation(value = "读取流程图片")
    @GetMapping("/readImage/procDefKey")
    public void readImageByKey(String procDefKey, HttpServletResponse response) {
        OutputStream os = null;
        BufferedImage image = null;
        try {
            image = ImageIO.read(flowDefinitionService.readImageByKey(procDefKey));
            response.setContentType("image/png");
            os = response.getOutputStream();
            if (image != null) {
                ImageIO.write(image, "png", os);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.flush();
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


    @Log(title = "读取流程图片）", businessType = BusinessType.OTHER, operatorType = OperatorType.OTHER)
    @ApiOperation(value = "读取流程图片")
    @GetMapping("/readImage/{deployId}")
    public void readImage(@PathVariable(value = "deployId") String deployId, HttpServletResponse response) {
        OutputStream os = null;
        BufferedImage image = null;
        try {
            image = ImageIO.read(flowDefinitionService.readImage(deployId));
            response.setContentType("image/png");
            os = response.getOutputStream();
            if (image != null) {
                ImageIO.write(image, "png", os);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.flush();
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}
